package com.conversationboard.config;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.sql.SQLException;
import java.util.Date;

import com.conversationboard.logger.LogMessageType;
import com.conversationboard.logger.Logger;
import com.conversationboard.model.propertybag.Property;
import com.conversationboard.model.propertybag.PropertyBag;
import com.conversationboard.serialisation.XmlSerialiser;

public class Configuration {

	private static Configuration instance = null;
	public String configurationFilePath = "";


	public static Configuration getInstance() {

		if (instance == null) {
			instance = new Configuration();
		}

		return instance;

	}


	public String getConfigurationFilePath() {
		return configurationFilePath;
	}


	public void setConfigurationFilePath(String configurationFilePath) {
		this.configurationFilePath = configurationFilePath;
	}


	public static void load() throws SQLException {

		Property configurationProperty = PropertyBag.get("configuration");

		if (configurationProperty != null) {
			XmlSerialiser<Configuration> serialiser = new XmlSerialiser<Configuration>();
			Configuration configuration = serialiser.deSerialise(configurationProperty.getValue());

			instance = configuration;
		}

	}


	public void store() throws SQLException {

		XmlSerialiser<Configuration> serialiser = new XmlSerialiser<Configuration>();
		String configuration = serialiser.serialise(instance);

		PropertyBag.put("configuration", configuration);
	}

	private String root;
	private String databaseUrl = "jdbc/ilxDataSource";
	private boolean allowHtmlPosts = false;
	private boolean allowBlockRegistration = true;

	/* In characters. Important to prevent denial of service attacks */
	private int maxMessageSize = 100000;

	/* This should always connection pooling in production. The variable is provided for debugging purposes. */
	private ConnectionStrategy connectionStrategy = ConnectionStrategy.ConnectionPooling;

	private boolean checkForDuplicateMessages = true;
	private boolean displayHumanTimes = true;

	/* This has the potential to be quite slow (a few milliseconds for each thread), since it counts them for
	 * each thread; probably turn on at first, but want to monitor. Could keep a counter up to date, but kind
	 * of trade off efficiency for complexity here and I'm not sure it's worth it. */
	private boolean displayNumberOfRecentMessages = true;

	/* Display the first x messages and the newest y messages. Place the link to display the entire thread at
	 * the end of the oldest messages to discourage people from just clicking on it; they need to find it
	 * first, and in many cases, won't need to, because the interesting stuff in a thread is typically at the
	 * start or what's just changed. */

	private int oldestMessageCount = 50;
	private int newestMessageCount = 50;

	/* For testing only; not for production use. Loads all of the new answers page of a board into the cache */

	private final boolean preloadCache = false;

	private int maxThreadCacheEntries = 1000;

	/* This could fail under Unix if an X server is unavailable, so allow it to be turned off. */

	private boolean captchaEnabled = false;

	/* If TEST_SERVER is set to true, then referrer checks are disabled to allow localhost to insert
	 * questions/messages. */

	private boolean testServer = false;
	private int maxImagesPerPost = 3;

	private String key = "UWI342315UY5G5FGT76tvytv3746VUY2V";
	private int banThreshold = 50;
	private String domainName = "localhost:8080";
	private String threadIndexPath = "/Users/Keith/Lucene/ILX/Threads";
	private String messageIndexPath = "/Users/Keith/Lucene/ILX/Messages";
	private String geoDatabasePath = "/Users/Keith/dev/Geo/GeoLiteCity.dat";

	private boolean emailSsl = false;
	private String smtpServer = "localhost";
	private int smtpPort = 25;
	private String smtpServerLoginId = "";
	private String smtpServerPassword = "";
	private boolean storeDatabaseConnectionInfo = true;
	private boolean allowUserBoardCreation = true;
	private String siteName = "ilXor.com";
	private boolean supportSuggestBan = false;
	private boolean suggestSimilarThreads = true;
	private boolean displayAdminLogToUsers = false;
	private boolean displayAdminLogToSiteAdmins = true;
	private boolean logSiteWideAdminActions = false;
	private boolean allowChangeOfUserName = false;
	private int maxPollItems = 20;
	private boolean adminsCanSeePictures = false;
	private boolean enableBlogView = false;
	private boolean showLocationDataOnMessagesForSiteAdmins = false;
	private boolean showPasswordImmediately = false;
	private boolean supportFileUploads = false;
	private String fileUploadRepository = "";
	private String fileUploadRepositoryUrl = ""; /* This is obsolete, but cannot remove without modifying
												 * configuration XML */
	private boolean usersCanSeeTheirRecentPosts = false;
	private boolean showNotWorksafeLinkForAdmins = true;
	private boolean validateBBCode = true;
	private boolean threadsPosts = false;
	private String defaultStyleSheet = "style.css";
	private boolean reportOnSockpuppets = false;
	private boolean siteOpenOnStartup = true;
	private boolean onlySupportImageUploads = false;
	private boolean deleteOldUsers = false;


	public boolean isOnlySupportImageUploads() {
		return onlySupportImageUploads;
	}


	public void setOnlySupportImageUploads(boolean onlySupportImageUploads) {
		this.onlySupportImageUploads = onlySupportImageUploads;
	}


	public boolean isSiteOpenOnStartup() {
		return siteOpenOnStartup;
	}


	public void setSiteOpenOnStartup(boolean siteOpenOnStartup) {
		this.siteOpenOnStartup = siteOpenOnStartup;
	}


	public boolean isEnableBlogView() {
		return enableBlogView;
	}


	public void setEnableBlogView(boolean enableBlogView) {
		this.enableBlogView = enableBlogView;
	}


	public boolean isAdminsCanSeePictures() {
		return adminsCanSeePictures;
	}


	public void setAdminsCanSeePictures(boolean adminsCanSeePictures) {
		this.adminsCanSeePictures = adminsCanSeePictures;
	}


	public int getMaxPollItems() {
		return maxPollItems;
	}


	public void setMaxPollItems(int maxPollItems) {
		this.maxPollItems = maxPollItems;
	}


	public boolean isAllowChangeOfUserName() {
		return allowChangeOfUserName;
	}


	public void setAllowChangeOfUserName(boolean allowChangeOfUserName) {
		this.allowChangeOfUserName = allowChangeOfUserName;
	}


	public boolean isLogSiteWideAdminActions() {
		return logSiteWideAdminActions;
	}


	public void setLogSiteWideAdminActions(boolean logSiteWideAdminActions) {
		this.logSiteWideAdminActions = logSiteWideAdminActions;
	}


	public boolean isDisplayAdminLogToUsers() {
		return displayAdminLogToUsers;
	}


	public void setDisplayAdminLogToUsers(boolean displayAdminLogToUsers) {
		this.displayAdminLogToUsers = displayAdminLogToUsers;
	}


	public boolean isDisplayAdminLogToSiteAdmins() {
		return displayAdminLogToSiteAdmins;
	}


	public void setDisplayAdminLogToSiteAdmins(boolean displayAdminLogToSiteAdmins) {
		this.displayAdminLogToSiteAdmins = displayAdminLogToSiteAdmins;
	}


	public boolean isSupportSuggestBan() {
		return supportSuggestBan;
	}


	public void setSupportSuggestBan(boolean supportSuggestBan) {
		this.supportSuggestBan = supportSuggestBan;
	}


	public String getSiteName() {
		return getInstance().siteName;
	}


	public boolean isAllowUserBoardCreation() {
		return getInstance().allowUserBoardCreation;
	}


	public boolean isStoreDatabaseConnectionInfo() {
		return getInstance().storeDatabaseConnectionInfo;
	}


	public String getSmtpServerLoginId() {
		return getInstance().smtpServerLoginId;
	}


	public String getSmtpServerPassword() {
		return getInstance().smtpServerPassword;
	}


	public boolean isEmailSsl() {
		return getInstance().emailSsl;
	}


	public String getSmtpServer() {
		return getInstance().smtpServer;
	}


	public int getSmtpPort() {
		return getInstance().smtpPort;
	}


	public String getThreadIndexPath() {
		return getInstance().threadIndexPath;
	}


	public String getMessageIndexPath() {
		return getInstance().messageIndexPath;
	}


	public String getDomainName() {
		return this.domainName;
	}


	public void setDomainName(String domain) {
		getInstance().domainName = domain;
	}


	public int getBanThreshold() {
		return getInstance().banThreshold;
	}


	public int getMaxImagesPerPost() {
		return getInstance().maxImagesPerPost;
	}


	public boolean isTestServer() {

		/* This is hardwired for my computer. If you're developing on a different computer, you will want to
		 * change the following to its name. */

		try {

			String name = InetAddress.getLocalHost().getHostName();

			if (name.contains("Polaris") || name.contains("Cruise")) {
				Logger.log(new Date(), "TEST SERVER POLARIS", null, LogMessageType.SYSTEM);
				return true;
			} else {
				return getInstance().testServer;
			}
		} catch (UnknownHostException e) {
			Logger.log(new Date(), "Failed in isTestServer: " + e.getMessage(), null, LogMessageType.SYSTEM);
		}

		return true;

	}


	public void setTestServer(boolean testServer) {
		getInstance().testServer = testServer;
	}


	public String getRoot() {
		return this.root;
	}


	public void setRoot(String contextPath) {
		this.root = contextPath;
	}


	public int getMaxMessageSize() {
		return getInstance().maxMessageSize;
	}


	public void setConnectionStrategy(ConnectionStrategy connectionStrategy) {
		getInstance().connectionStrategy = connectionStrategy;
	}


	public ConnectionStrategy getConnectionStrategy() {
		return getInstance().connectionStrategy;
	}


	public void setCheckForDuplicateMessages(boolean checkForDuplicateMessages) {
		getInstance().checkForDuplicateMessages = checkForDuplicateMessages;
	}


	public boolean isCheckForDuplicateMessages() {
		return getInstance().checkForDuplicateMessages;
	}


	public boolean isDisplayHumanTimes() {
		return getInstance().displayHumanTimes;
	}


	public boolean isDisplayNumberOfRecentMessages() {
		return getInstance().displayNumberOfRecentMessages;
	}


	public int getOldestMessageCount() {
		return getInstance().oldestMessageCount;
	}


	public int getNewestMessageCount() {
		return getInstance().newestMessageCount;
	}


	public boolean isPreloadCache() {
		return getInstance().preloadCache;
	}


	public int getMaxThreadCacheEntries() {
		return getInstance().maxThreadCacheEntries;
	}


	public boolean isCaptchaEnabled() {
		return getInstance().captchaEnabled;
	}


	public String getKey() {
		return getInstance().key;
	}


	public boolean isAllowHtmlPosts() {
		return getInstance().allowHtmlPosts;
	}


	public String getDatabaseUrl() {
		return getInstance().databaseUrl;
	}


	public boolean isAllowBlockRegistration() {
		return getInstance().allowBlockRegistration;
	}


	public static void setInstance(Configuration instance) {
		Configuration.instance = instance;
	}


	public void setDatabaseUrl(String databaseUrl) {
		this.databaseUrl = databaseUrl;
	}


	public void setAllowHtmlPosts(boolean allowHtmlPosts) {
		this.allowHtmlPosts = allowHtmlPosts;
	}


	public void setAllowBlockRegistration(boolean allowBlockRegistration) {
		this.allowBlockRegistration = allowBlockRegistration;
	}


	public void setMaxMessageSize(int maxMessageSize) {
		this.maxMessageSize = maxMessageSize;
	}


	public void setDisplayHumanTimes(boolean displayHumanTimes) {
		this.displayHumanTimes = displayHumanTimes;
	}


	public void setDisplayNumberOfRecentMessages(boolean displayNumberOfRecentMessages) {
		this.displayNumberOfRecentMessages = displayNumberOfRecentMessages;
	}


	public void setOldestMessageCount(int oldestMessageCount) {
		this.oldestMessageCount = oldestMessageCount;
	}


	public void setNewestMessageCount(int newestMessageCount) {
		this.newestMessageCount = newestMessageCount;
	}


	public void setMaxThreadCacheEntries(int maxThreadCacheEntries) {
		this.maxThreadCacheEntries = maxThreadCacheEntries;
	}


	public void setCaptchaEnabled(boolean captchaEnabled) {
		this.captchaEnabled = captchaEnabled;
	}


	public void setMaxImagesPerPost(int maxImagesPerPost) {
		this.maxImagesPerPost = maxImagesPerPost;
	}


	public void setKey(String key) {
		this.key = key;
	}


	public void setBanThreshold(int banThreshold) {
		this.banThreshold = banThreshold;
	}


	public void setThreadIndexPath(String threadIndexPath) {
		this.threadIndexPath = threadIndexPath;
	}


	public void setMessageIndexPath(String messageIndexPath) {
		this.messageIndexPath = messageIndexPath;
	}


	public void setEmailSsl(boolean isEmailSsl) {
		this.emailSsl = isEmailSsl;
	}


	public void setSmtpServer(String smtpServer) {
		this.smtpServer = smtpServer;
	}


	public void setSmtpPort(int smtpPort) {
		this.smtpPort = smtpPort;
	}


	public void setSmtpServerLoginId(String smtpServerLoginId) {
		this.smtpServerLoginId = smtpServerLoginId;
	}


	public void setSmtpServerPassword(String smtpServerPassword) {
		this.smtpServerPassword = smtpServerPassword;
	}


	public void setStoreDatabaseConnectionInfo(boolean storeDatabaseConnectionInfo) {
		this.storeDatabaseConnectionInfo = storeDatabaseConnectionInfo;
	}


	public void setAllowUserBoardCreation(boolean allowUserBoardCreation) {
		this.allowUserBoardCreation = allowUserBoardCreation;
	}


	public void setSiteName(String siteName) {
		this.siteName = siteName;
	}


	public boolean isSuggestSimilarThreads() {
		return suggestSimilarThreads;
	}


	public void setSuggestSimilarThreads(boolean suggestSimilarThreads) {
		this.suggestSimilarThreads = suggestSimilarThreads;
	}


	public String getGeoDatabasePath() {
		return geoDatabasePath;
	}


	public void setGeoDatabasePath(String geoDatabasePath) {
		this.geoDatabasePath = geoDatabasePath;
	}


	public boolean isShowLocationDataOnMessagesForSiteAdmins() {
		return showLocationDataOnMessagesForSiteAdmins;
	}


	public void setShowLocationDataOnMessagesForSiteAdmins(boolean showLocationDataOnMessagesForSiteAdmins) {
		this.showLocationDataOnMessagesForSiteAdmins = showLocationDataOnMessagesForSiteAdmins;
	}


	public boolean isShowPasswordImmediately() {
		return showPasswordImmediately;
	}


	public void setShowPasswordImmediately(boolean showPasswordImmediately) {
		this.showPasswordImmediately = showPasswordImmediately;
	}


	public boolean isSupportFileUploads() {
		return supportFileUploads;
	}


	public void setSupportFileUploads(boolean supportFileUploads) {
		this.supportFileUploads = supportFileUploads;
	}


	public String getFileUploadRepository() {
		return fileUploadRepository;
	}


	public void setFileUploadRepository(String fileUploadRepository) {
		this.fileUploadRepository = fileUploadRepository;
	}


	public String getFileUploadRepositoryUrl() {
		return fileUploadRepositoryUrl;
	}


	public void setFileUploadRepositoryUrl(String fileUploadRepositoryUrl) {
		this.fileUploadRepositoryUrl = fileUploadRepositoryUrl;
	}


	public boolean isUsersCanSeeTheirRecentPosts() {
		return usersCanSeeTheirRecentPosts;
	}


	public void setUsersCanSeeTheirRecentPosts(boolean usersCanSeeTheirRecentPosts) {
		this.usersCanSeeTheirRecentPosts = usersCanSeeTheirRecentPosts;
	}


	public boolean isShowNotWorksafeLinkForAdmins() {
		return showNotWorksafeLinkForAdmins;
	}


	public void setShowNotWorksafeLinkForAdmins(boolean showNotWorksafeLinkForAdmins) {
		this.showNotWorksafeLinkForAdmins = showNotWorksafeLinkForAdmins;
	}


	public boolean isValidateBBCode() {
		return validateBBCode;
	}


	public void setValidateBBCode(boolean validateBBCode) {
		this.validateBBCode = validateBBCode;
	}


	public boolean isThreadsPosts() {
		return threadsPosts;
	}


	public void setThreadsPosts(boolean threadsPosts) {
		this.threadsPosts = threadsPosts;
	}


	public String getDefaultStyleSheet() {
		return defaultStyleSheet;
	}


	public void setDefaultStyleSheet(String defaultStyleSheet) {
		this.defaultStyleSheet = defaultStyleSheet;
	}


	public boolean isReportOnSockpuppets() {
		return reportOnSockpuppets;
	}


	public void setReportOnSockpuppets(boolean reportOnSockpuppets) {
		this.reportOnSockpuppets = reportOnSockpuppets;
	}


	public boolean isDeleteOldUsers() {
		return deleteOldUsers;
	}


	public void setDeleteOldUsers(boolean deleteOldUsers) {
		this.deleteOldUsers = deleteOldUsers;
	}

}
